package cn.micai.base.thread;

import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 描述：并发类容器之Queue
 * <p>
 *
 * @author: 赵新国
 * @date: 2018/2/22 16:23
 */
public class UseQueue1 {

    /**
     *
     * ConcurrentLinkedQueue：是一个适用于高并发场景下的队列，通过无锁的方式，实现了高并发状态下的高性能，通常ConcurrentLinkedQueue性能好于BlockingQueue。它是一个基于链接节点的无界线程安全队列。该队列的元素遵循先进先出的原则。头是最先加入的，尾是最近加入的，该队列不允许null元素。
     ConcurrentLinkedQueue重要方法：
     add()和offer()都是加入元素的方法（在ConcurrentLinkedQueue中，这两个方法没有任何区别，大家可能有疑问，既然两个没有区别为何还要弄两个方法，这是因为这两个方法都继承自父类Queue，在其它场景下是可能不一样的）
     poll()和peek()都是取头元素节点，区别在于前者会删除元素，后者不会。
     下面我们来看个例子，如下所示。这是最常用的几个方法。
     * @param args
     */
    public static void main(String [] args) {
        // 高性能无阻塞无界队列：ConcurrentLinkedQueue
        ConcurrentLinkedQueue<String> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();

        concurrentLinkedQueue.offer("a");

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                //不要使用.size()方法，因为那样效率非常低
                if(!concurrentLinkedQueue.isEmpty()){
                    System.out.println("进入线程1");
                    String str = concurrentLinkedQueue.poll();
                    System.out.println("线程1取出的元素："+str);
                }
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                //不要使用.size()方法，因为那样效率非常低
                if(!concurrentLinkedQueue.isEmpty()){
                    System.out.println("进入线程2");
                    String str = concurrentLinkedQueue.poll();
                    System.out.println("线程2取出的元素："+str);
                }
            }
        },"t2");

        Thread t3 = new Thread(new Runnable() {

            @Override
            public void run() {
                //不要使用.size()方法，因为那样效率非常低
                if(!concurrentLinkedQueue.isEmpty()){
                    System.out.println("进入线程3");
                    String str = concurrentLinkedQueue.poll();
                    System.out.println("线程3取出的元素："+str);
                }
            }
        },"t3");

        Thread t4 = new Thread(new Runnable() {

            @Override
            public void run() {
                //不要使用.size()方法，因为那样效率非常低
                if(!concurrentLinkedQueue.isEmpty()){
                    System.out.println("进入线程4");
                    String str = concurrentLinkedQueue.poll();
                    System.out.println("线程4取出的元素："+str);
                }
            }
        },"t4");

        Thread t5 = new Thread(new Runnable() {

            @Override
            public void run() {
                //不要使用.size()方法，因为那样效率非常低
                if(!concurrentLinkedQueue.isEmpty()){
                    System.out.println("进入线程5");
                    String str = concurrentLinkedQueue.poll();
                    System.out.println("线程5取出的元素："+str);
                }
            }
        },"t5");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();

    }
}
